package cn.casc.tools.maven;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Optional;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.logging.Logger;

/**
 * @author max
 * @version 1.0.1
 * @className MavenJarUploader
 * @description
 * @copyright Copyright (c) 2023
 * @company 天纲梦工厂
 * @datetime 2024/7/18 13:54
 **/

public class JarUploader {
    final static Logger LOGGER = Logger.getLogger(JarUploader.class.getName());
    public String groupId;
    public String artifactId;
    public String version;

    public static JarUploader get(JarFile jarFile){
        Optional<JarEntry> optionalJarEntry =
                jarFile.stream().filter((f) -> f.getName().startsWith("META-INF/") && f.getName().endsWith("/pom" +
                        ".properties")).findFirst();
        if(!optionalJarEntry.isPresent()) {
            return null;
        }
        JarEntry jarEntry = optionalJarEntry.get();
        byte[] buf = new byte[8192];
        try(InputStream is = jarFile.getInputStream(jarEntry)) {
            int len = is.read(buf);
            String info = new String(buf,0, len, "UTF-8");
            String[] lines = info.split("\n");
            JarUploader result = new JarUploader();
            for(String line:lines) {
                String[] kv = line.split("=");
                switch (kv[0]) {
                    case "groupId":
                        result.groupId = kv[1].trim();
                        break;
                    case "artifactId":
                        result.artifactId = kv[1].trim();
                        break;
                    case "version":
                        result.version = kv[1].trim();
                        break;
                }
            }
            return result;
        } catch (Exception e) {
            LOGGER.fine(e.getMessage());
        }
        return null;
    }

    public static String uploadWithInfo(JarFile jarFile, String pomUrl) throws IOException {
        if(!pomUrl.matches("^[^<>]+:[^<>]+:[^<>]+$")) {
            return "输入pom信息不正确。";
        }
        String[] pomInfos = pomUrl.split(":");
        File tmpFile =  File.createTempFile("er-tools", ".jar");
        try (FileOutputStream fos = new FileOutputStream(tmpFile); JarOutputStream os = new JarOutputStream(fos)) {
            byte[] buf = new byte[8192];
            int len = -1;
            Enumeration<JarEntry> enumeration =  jarFile.entries();
            while (enumeration.hasMoreElements()) {
                JarEntry pre = enumeration.nextElement();
                JarEntry entry = new JarEntry(pre.getName());
                os.putNextEntry(entry);
                try (InputStream is = jarFile.getInputStream(pre)) {
                    while ((len =is.read(buf)) > 0) {
                        os.write(buf, 0, len);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    LOGGER.fine(e.getMessage());
                }
            }
            String pomName = String.format("META-INF/maven/%s/%s/", pomInfos[0], pomInfos[1]);
            pushJarEntry(os, pomName+"pom.properties",String.format(propertiesTpl, pomInfos[0], pomInfos[1],
                    pomInfos[2]));
            pushJarEntry(os, pomName+"pom.xml",String.format(xmlTpl, pomInfos[0], pomInfos[1],
                    pomInfos[2], pomInfos[1]));

        } catch (Exception e) {
            LOGGER.fine(e.getMessage());
        }
        String error = upload(new JarFile(tmpFile));
        tmpFile.delete();
        return error;
    }
    public static final String propertiesTpl = "groupId=%s\nartifactId=%s\nversion=%s";

    public static final String xmlTpl = "<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n" +
            "\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
            "\txsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
            "\t<modelVersion>4.0.0</modelVersion>\n" +
            "\t<groupId>%s</groupId>\n" +
            "\t<artifactId>%s</artifactId>\n" +
            "\t<version>%s</version>\n" +
            "\t<name>%s</name>\n" +
            "\t<description></description>\n" +
            "\t<url>https://gitee.com/dmedu/dm-jdbc-jars</url>\n" +
            "</project>";

    public static void pushJarEntry(JarOutputStream os, String name,String content) throws IOException {
        JarEntry entry = new JarEntry(name);
        os.putNextEntry(entry);
        os.write(content.getBytes());
    }

    public static String JAR_ERROR = "读取jar文件pom信息失败";
    public static String upload(JarFile jarFile) {
        JarUploader jarID = get(jarFile);
        if(jarID == null) {
            return JAR_ERROR;
        }
        if(jarID != null) {
            String cmd = String.format(Config.get().releaseMvnCmd, jarID.groupId, jarID.artifactId,
                    jarID.version, jarFile.getName());
            if(jarID.version.endsWith("SNAPSHOT")){
                cmd = String.format(Config.get().snapshotMvnCmd, jarID.groupId, jarID.artifactId,
                        jarID.version, jarFile.getName());
            }
            LOGGER.info(cmd);
            Runtime runtime = Runtime.getRuntime();
            try {
                Process process = runtime.exec(cmd);
                byte[] buf = new byte[8192];
                StringBuilder sbError = new StringBuilder();
                int len;
                try(InputStream is = process.getInputStream()) {
                    do {
                        len = is.read(buf);
                        String err = new String(buf, 0, len, "UTF-8");
                        sbError.append(err);
                        LOGGER.info(err);
                        Thread.sleep(200);
                    } while(process.isAlive());
                } catch (Exception e) {
                    LOGGER.fine(cmd);
                }
                int er = process.exitValue();
                if(er != 0) {
                    return sbError.toString();
                }
            } catch (IOException e) {
                LOGGER.fine(e.getMessage());
                return e.getMessage();
            }
        }
        return null;
    }
}